package service

import (
	"context"
	"mini-app/internal/app/grpc/client"
	"mini-app/internal/app/grpc/protoc/devicec"
	"mini-app/internal/app/grpc/protoc/sale_adminc"
	"mini-app/internal/dal"
	"mini-app/internal/dao"

	"192.168.1.75/go-pkg/logx"
	"github.com/go-redis/redis/v8"
	"github.com/shopspring/decimal"
)

type ShoppingCart struct{}

func (ShoppingCart) Save(ctx context.Context, openid, robotName, goodsID string, count int) (err error) {
	if count == 0 {
		err = dao.ShoppingCart{}.Delete(ctx, dal.Q, openid, robotName, goodsID)
		return
	}
	cartInfo, _ := dao.ShoppingCart{}.Detail(ctx, dal.Q, openid, robotName, goodsID)
	if cartInfo == nil { // 新增
		dao.ShoppingCart{}.Create(ctx, dal.Q, openid, robotName, goodsID, count)
	} else { // 更新
		dao.ShoppingCart{}.Save(ctx, dal.Q, openid, robotName, goodsID, count)
	}
	return
}

type Cart struct {
	RobotName string      `json:"robot_name"`
	Location  string      `json:"location"`
	Floor     string      `json:"floor"`
	Distance  float64     `json:"distance"`
	Goods     []CartGoods `json:"goods"`
}

type CartGoods struct {
	GoodsID    string  `json:"goods_id"`
	GoodsName  string  `json:"goods_name"`
	GoodsImage string  `json:"goods_image"`
	Price      float64 `json:"price"`
	Count      int     `json:"count"`
}

// 购物车列表【设备分组】
func (ShoppingCart) List(ctx context.Context, openid string, longitude, latitude *float64) (data []Cart, err error) {
	geoLocation, err := GeoRadius(longitude, latitude)
	if len(geoLocation) == 0 || err != nil {
		return
	}
	var RobotLocationMap = make(map[string]redis.GeoLocation)
	for _, v := range geoLocation {
		RobotLocationMap[v.Name] = v
	}

	// 购物车信息
	list, _ := dao.ShoppingCart{}.List(ctx, dal.Q, openid)

	// 商品信息
	saleAdminClient, clientErr := client.GetSaleAdminClient()
	if clientErr != nil {
		logx.Error(ctx, "connect sale admin client fail", logx.Any("err", clientErr))
		return
	}
	goodsListRsp, _ := saleAdminClient.AllGoodsList(context.Background(), &sale_adminc.AllGoodsListReq{})
	GoodsMap := make(map[string]CartGoods)
	for _, v := range goodsListRsp.Data.List {
		GoodsMap[v.GoodsId] = CartGoods{
			GoodsName:  v.GoodsName,
			GoodsImage: v.GoodsImage,
			Price:      decimal.NewFromInt(v.Price).Div(decimal.NewFromInt(100)).InexactFloat64(),
		}
	}
	robotGoodsMap := make(map[string][]CartGoods)
	for _, v := range list {
		var goodsName, goodsImage string
		var price float64
		if _, ok := GoodsMap[v.GoodsID]; ok {
			goodsName = GoodsMap[v.GoodsID].GoodsName
			goodsImage = GoodsMap[v.GoodsID].GoodsImage
			price = GoodsMap[v.GoodsID].Price
		}
		robotGoodsMap[v.RobotName] = append(robotGoodsMap[v.RobotName], CartGoods{
			GoodsID:    v.GoodsID,
			GoodsName:  goodsName,
			GoodsImage: goodsImage,
			Price:      price,
			Count:      v.Count,
		})
	}
	deviceClient, deviceClientErr := client.GetAdminClient()
	if deviceClientErr != nil {
		logx.Error(ctx, "connect device grpc error", logx.Any("deviceClientErr", deviceClientErr))
		return
	}
	for k, v := range robotGoodsMap {
		item := Cart{}
		item.RobotName = k
		item.Goods = v

		// 获取设备详情
		deviceInfo, DeviceErr := deviceClient.DeviceDetail(ctx, &devicec.DeviceDetailReq{RobotId: k})
		if DeviceErr != nil || deviceInfo.Code != 0 {
			return
		}
		// 获取位置信息
		req := &devicec.LocationDetailReq{
			LocationId: deviceInfo.Device.LocationId,
		}
		locationDetail, locationErr := deviceClient.LocationDetail(ctx, req)
		if locationErr != nil || locationDetail.Location == nil {
			logx.Error(ctx, "get location detail error", logx.Any("locationErr", locationErr))
			return
		}
		item.Location = locationDetail.Location.Name
		item.Floor = deviceInfo.Device.Floor
		if _, ok := RobotLocationMap[k]; ok {
			item.Distance = RobotLocationMap[k].Dist
		}
		data = append(data, item)
	}
	return
}
